package logic;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.apache.log4j.Logger;

import javax.management.monitor.Monitor;
import java.net.InetSocketAddress;
import java.util.Calendar;

public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    private NettyServer nettyServer;


    // 配置信息
    private final ConfigInfo configInfo = ConfigInfo.getInstance();
    // 日志对象
    private final static Logger logger = Logger.getLogger(NettyServerHandler.class);
    // 工具类对象
    private final Utils utils = new Utils();

    public NettyServerHandler(NettyServer nettyServer) {
        this.nettyServer = nettyServer;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
        // 收到的帧
        String recFrame = null;
        if (configInfo.encoderStyle == 1) {
            ByteBuf receBuf = (ByteBuf) obj;
            byte[] recBytes = new byte[receBuf.readableBytes()];
            receBuf.readBytes(recBytes); //将缓存区的字节数组复制到新建的req数组中
            recFrame = Utils.bytesToHexString(recBytes);
        } else {
            // 字符串编解码器传输
            recFrame = (String) obj;
        }
        logger.info("收到客户端心跳帧：" + recFrame);

        if (configInfo.encoderStyle == 1) {
            //logger.info("发送数据："+msg);
            // 字节数组传输
            byte[] sByte = utils.hexStringToBytes(configInfo.responseFrame);
            ByteBuf byteBuf = Unpooled.wrappedBuffer(sByte);
            // 发送消息
            ctx.channel().writeAndFlush(byteBuf);
        } else {
            // 发送字符串消息
            ctx.channel().writeAndFlush(configInfo.responseFrame);
        }
        logger.info("回应客户端消息：" + configInfo.responseFrame);

        /*String clientName = channelHandlerContext.channel().remoteAddress().toString();
        // 回复消息
        nettyServer.writeMsg(clientName, configInfo.responseFrame);
        logger.info("回应客户端消息：" + configInfo.responseFrame);*/

    }

    /**
     * 在与客户端的连接已经建立之后将被调用
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String clientName = ctx.channel().remoteAddress().toString();
        logger.info("远程地址:" + clientName + "通道已激活!");
        //nettyServer.setChannel(clientName,ctx.channel());
        ChannelMap.addChannel(clientName,ctx.channel());
        //super.channelActive(ctx);
    }

    /**
     * 客户端与服务端断开连接时调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("客户端与服务端连接关闭...");
        String clientName = ctx.channel().remoteAddress().toString();
        //nettyServer.getChannelMap().remove(clientName);
        ChannelMap.removeChannelByName(clientName);
    }

    /**
     * 在处理过程中引发异常时被调用
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
        System.out.println("异常信息：rn " + cause.getMessage());
    }

    /*@Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state().equals(IdleState.READER_IDLE)) {
                //空闲4s后触发
                if (counter >= 10) {
                    ctx.channel().close().sync();
                    String clientName = ctx.channel().remoteAddress().toString();
                    System.out.println("" + clientName + "offline");
                    nettyServer.removeClient(clientName);
                    //判断是否有在线的
                    if (nettyServer.getClientMapSize()) {
                        return;
                    }
                } else {
                    counter++;
                    System.out.println("loss" + counter + "count HB");
                }
            }
        }
    }*/
}